﻿using System;
using System.Linq;
using System.Reactive.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Rxx.UnitTests.Reactive
{
	public partial class TraceTests : RxxTraceTests
	{
		[TestMethod]
		public void RxTraceSource()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.Trace(source).Subscribe();

			AssertEqual(Listener.Messages, Concat(
				Enumerable.Range(0, 5).Select(value => TraceDefaults.DefaultOnNext(value)),
				TraceDefaults.DefaultOnCompleted()));
		}

		[TestMethod]
		public void RxTraceSourceOnNext()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnNext(source).Subscribe();

			AssertEqual(Listener.Messages, Enumerable.Range(0, 5).Select(value => TraceDefaults.DefaultOnNext(value)));
		}

		[TestMethod]
		public void RxTraceSourceOnNextFormat()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnNext(source, "OnNext: {0}").Subscribe();

			AssertEqual(Listener.Messages, Enumerable.Range(0, 5).Select(value => "OnNext: " + value));
		}

		[TestMethod]
		public void RxTraceSourceOnNextLazyMessage()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnNext(source, value => "OnNext: " + value).Subscribe();

			AssertEqual(Listener.Messages, Enumerable.Range(0, 5).Select(value => "OnNext: " + value));
		}

		[TestMethod]
		public void RxTraceSourceOnError()
		{
			var source = CreateTraceSource();

			var ex = new Exception("Error");
			var xs = Observable.Throw<int>(ex);

			xs.TraceOnError(source).Subscribe(_ => { }, __ => { });

			AssertEqual(Listener.Messages, TraceDefaults.DefaultOnError(ex));
		}

		[TestMethod]
		public void RxTraceSourceOnErrorFormat()
		{
			var source = CreateTraceSource();

			var ex = new Exception("Error");
			var xs = Observable.Throw<int>(ex);

			xs.TraceOnError(source, "OnError: {0}").Subscribe(_ => { }, __ => { });

			AssertEqual(Listener.Messages, "OnError: " + ex.ToString());
		}

		[TestMethod]
		public void RxTraceSourceOnErrorLazyMessage()
		{
			var source = CreateTraceSource();

			var ex = new Exception("Error");
			var xs = Observable.Throw<int>(ex);

			xs.TraceOnError(source, error => "OnError: " + error.Message).Subscribe(_ => { }, __ => { });

			AssertEqual(Listener.Messages, "OnError: " + ex.Message);
		}

		[TestMethod]
		public void RxTraceSourceOnCompleted()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnCompleted(source).Subscribe();

			AssertEqual(Listener.Messages, TraceDefaults.DefaultOnCompleted());
		}

		[TestMethod]
		public void RxTraceSourceOnCompletedFormat()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnCompleted(source, "OnCompleted").Subscribe();

			AssertEqual(Listener.Messages, "OnCompleted");
		}

		[TestMethod]
		public void RxTraceSourceOnCompletedLazyMessage()
		{
			var source = CreateTraceSource();

			var xs = Observable.Range(0, 5);

			xs.TraceOnCompleted(source, () => "OnCompleted").Subscribe();

			AssertEqual(Listener.Messages, "OnCompleted");
		}
	}
}